<template>
	<div class="greetings">
		<input type="file" name="file" @change="change" />
		<span>进度条：{{ percent }}</span>
	</div>
</template>
<script setup lang="ts">
import axios from 'axios'
import md5 from 'md5'
import { ref } from 'vue'

// 进度条
const percent = ref(0)

// 触发文件选择
async function change(e: Event) {
	let chunkSize = 1024 * 1024 * 1 // 1MB
	let start = 0 // 开始位置
	let index = 0 // 分片索引
	let target = e.target as HTMLInputElement

	if (target.files) {
		// 获取文件对象
		const file = target.files[0]
		// 获取文件名称和大小
		const { name, size } = file
		// while循环分片上传，开始位置小于文件大小
		while (start < size) {
			let blob = null
			// 开始位置加上分片大小大于文件大小，说明是最后一片
			if (start + chunkSize > size) {
				blob = file.slice(start, size)
			} else {
				// 开始位置加上分片大小进行切片
				blob = file.slice(start, start + chunkSize)
			}
			// 开始位置加上分片大小
			start += chunkSize
			// new File对象，第一个参数是文件对象，第二个参数是文件名称
			let blobFile: any = new File([blob], `${name}`)
			// new Formdata对象
			let formData: any = new FormData()
			// 添加文件对象和分片索引到formData对象
			formData.append('file', blobFile)
			// 添加文件对象和分片索引到formData对象
			formData.append('index', index + '')
			// 上传文件分片
			await axios.get('/api/upload', formData)
			// 文件索引++
			index++
			// 计算进度条百分比
			percent.value = Number.parseInt(`${(start / size) * 100}`)
		}
		// 循环上传分片完成后，合并文件
		axios.get('/api/merge?dir=' + md5(name))
		// 处理进度条100%
		percent.value = 100
	}
}
</script>

<style scoped></style>
